package com.cai.provider;

import com.cai.entity.PO.UserDetailsImpl;
import com.cai.service.impl.UserDetailsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @Title: UsernamePasswordAuthenticationProvider
 * @Author RuoLi
 * @Package com.cai.provider
 * @Date 2024/1/12 10:35
 * @description:
 */
@Component
@Slf4j
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
        //验证用户名和密码
        String principal = (String) authentication.getPrincipal();
        String credentials = (String) authentication.getCredentials();
        UserDetailsImpl details = (UserDetailsImpl) userDetailsService.loadUserByUsername(principal);

        //检查密码是否正确
        if (!new BCryptPasswordEncoder().matches(credentials, details.getPassword())) {
            throw new BadCredentialsException("密码输入错误");
        }

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(details, details.getPassword(), details.getAuthorities());
        usernamePasswordAuthenticationToken.setDetails(authenticationToken.getDetails());
        return usernamePasswordAuthenticationToken;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
